package game.logic;

import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.collect.EvictingQueue;

import game.module.question.ProtoMessageQuestion.S2CChatPush;

public class ServerCache {

	private static Logger logger = LoggerFactory.getLogger(ServerCache.class);

	private EvictingQueue<S2CChatPush> chatPublic = EvictingQueue.create(50);

	private Map<Integer, EvictingQueue<S2CChatPush>> chatPrivate = new ConcurrentHashMap<Integer, EvictingQueue<S2CChatPush>>();

	private Map<Integer, EvictingQueue<S2CChatPush>> chatGuild = new ConcurrentHashMap<Integer, EvictingQueue<S2CChatPush>>();

	final ReadWriteLock publicLock = new ReentrantReadWriteLock();

	private Map<Integer, Date> activityLastUpdateTimeMap = new HashMap<Integer, Date>();

	private Map<Integer, Long> fengHaoPlayers = new ConcurrentHashMap<>();

	private Map<Integer, Long> jinYanPlayers = new ConcurrentHashMap<>();

	static class SingletonHolder {
		static ServerCache instance = new ServerCache();
	}

	public static ServerCache getInstance() {
		return SingletonHolder.instance;
	}

	public void addChatPublic(S2CChatPush msg) {
		publicLock.writeLock().lock();
		try {
			chatPublic.add(msg);
		} finally {
			publicLock.writeLock().unlock();
		}
	}
	
	public void removeChatPublic(int playerId) {
		publicLock.writeLock().lock();
		try {
			for (Iterator<S2CChatPush> it = chatPublic.iterator(); it.hasNext();) {
				S2CChatPush s = it.next();
				if (s.getSenderUid() == playerId) {
					it.remove();
				}
			}
		} finally {
			publicLock.writeLock().unlock();
		}
	}

	public void addChatPrivate(int playerId, S2CChatPush msg) {
		EvictingQueue<S2CChatPush> chatQueue = chatPrivate.get(playerId);
		if (chatQueue == null) {
			chatQueue = EvictingQueue.create(50);
			chatPrivate.put(playerId, chatQueue);
		}
		chatQueue.add(msg);
	}

	public void addChatGuild(int guildId, S2CChatPush msg) {
		EvictingQueue<S2CChatPush> chatQueue = chatGuild.get(guildId);
		if (chatQueue == null) {
			chatQueue = EvictingQueue.create(50);
			chatGuild.put(guildId, chatQueue);
		}
		chatQueue.add(msg);
	}

	public Collection<S2CChatPush> getChatGuild(int guildId) {
		EvictingQueue<S2CChatPush> chatQueue = chatGuild.get(guildId);
		return chatQueue;
	}

	public Collection<S2CChatPush> getChatPrivate(int playerId) {
		EvictingQueue<S2CChatPush> chatQueue = chatPrivate.get(playerId);
		return chatQueue;
	}

	public Date getActivityLastUpdateTime(Integer activityId) {
		return activityLastUpdateTimeMap.get(activityId);
	}

	public void setActivityLastUpdateTime(Integer activityId, Date activityLastUpdateTime) {
		activityLastUpdateTimeMap.put(activityId, activityLastUpdateTime);
	}

	public void addFengHao(Integer playerId, Long endTime) {
		fengHaoPlayers.put(playerId, endTime);
	}

	public void removeFengHao(Integer playerId) {
		fengHaoPlayers.remove(playerId);
	}

	public boolean isFengHao(Integer playerId) {
		boolean ret = false;
		Long endTime = fengHaoPlayers.get(playerId);
		if (endTime != null) {
			ret = endTime > System.currentTimeMillis();
		}
		return ret;
	}

	public void addJinYan(int playerId, long endTime) {
		jinYanPlayers.put(playerId, endTime);
	}

	public void cancelJinYan(int playerId) {
		jinYanPlayers.remove(playerId);
	}

	public boolean isJinYan(int playerId) {
		boolean ret = false;
		Long endTime = jinYanPlayers.get(playerId);
		if (endTime != null) {
			ret = endTime > System.currentTimeMillis();
		}
		return ret;
	}

	public Map<Integer, Long> getFenghaoAll() {
		return fengHaoPlayers;
	}

}
